<template>
  <div class="container-publish">
    <el-card>
      <div slot="header">
        <my-bread>{{$route.query.id?'修改文章':'发布文章'}}</my-bread>
      </div>
      <!-- 表单 -->
      <el-form ref="articleForm" :model="articleForm" :rules="articleRules" label-width="120px">
        <el-form-item label="标题：" prop="title">
          <el-input v-model="articleForm.title" placeholder="请输入文章标题" style="width:400px"></el-input>
        </el-form-item>
        <el-form-item label="内容：" prop="content">
          <!-- trigger:blur 无法监听富文本失去焦点去进行校验 -->
          <!-- 自己绑定富文本的失去焦点事件，在事件处理函数中对改字段进行校验即可 -->
          <quill-editor @blur="checkContent()" v-model="articleForm.content" :options="editorOption" />
        </el-form-item>
        <el-form-item label="封面：" prop="cover.type">
          <el-radio-group @change="articleForm.cover.images=[]" v-model="articleForm.cover.type">
            <el-radio :label="1">单图</el-radio>
            <el-radio :label="3">三图</el-radio>
            <el-radio :label="0">无图</el-radio>
            <el-radio :label="-1">自动</el-radio>
          </el-radio-group>
          <!-- 一张 -->
          <div style="margin-top:10px" v-if="articleForm.cover.type===1">
            <my-image @confirm="checkCover()" v-model="articleForm.cover.images[0]"></my-image>
          </div>
          <!-- 三张 -->
          <div style="margin-top:10px" v-if="articleForm.cover.type===3">
            <my-image @confirm="checkCover()" v-for="i in 3" :key="i" v-model="articleForm.cover.images[i-1]"></my-image>
          </div>
        </el-form-item>
        <el-form-item label="频道：" prop="channel_id">
          <my-channel v-model="articleForm.channel_id"></my-channel>
        </el-form-item>
        <el-form-item v-if="$route.query.id">
          <el-button @click="editArticle()" type="success">修改文章</el-button>
        </el-form-item>
        <el-form-item v-else >
          <el-button @click="saveArticle(false)" type="primary">发布文章</el-button>
          <el-button @click="saveArticle(true)">存入草稿</el-button>
        </el-form-item>
      </el-form>
    </el-card>
    <!-- 测试使用：sync修饰符 -->
    <!-- <my-prop-sync :myMsg="msg" @update:myMsg="msg=$event"></my-prop-sync> -->
    <!-- <my-prop-sync :myMsg.sync="msg"></my-prop-sync> -->
  </div>
</template>

<script>
// 富文本样式
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
// 导入组件
import { quillEditor } from 'vue-quill-editor'
// import MyPropSync from '@/components/my-prop-sync'
export default {
  name: 'page-publish',
  // 注册组件
  components: { quillEditor /*, MyPropSync */ },
  data () {
    // 校验封面数据
    const validCoverFn = (rule, value, callback) => {
      // value 封面类型：1 3 0 -1 这些类型，就是cover.type
      // - cover.type === 1 单图，cover.images['图片地址']  必须有且只有一张图片。
      // - cover.type === 3 三图，cover.images['地址1','地址2','地址3'] 必须有三张图
      const images = this.articleForm.cover.images
      if (value === 1) {
        // 单图校验逻辑
        if (images[0] && images.length === 1) {
          callback()
        } else {
          callback(new Error('请选择一张封面图'))
        }
      } else if (value === 3) {
        // 三图校验逻辑
        if (images[0] && images[1] && images[2]) {
          callback()
        } else {
          callback(new Error('请选择三张封面图'))
        }
      } else {
        callback()
      }
    }
    return {
      // 测试数据
      msg: '父组件数据',
      // 文章表单数据对象
      articleForm: {
        title: null,
        channel_id: null,
        content: null,
        cover: {
          type: 1,
          images: []
        }
      },
      // 文章校验规则对象
      articleRules: {
        title: [
          { required: true, message: '请输入文章标题', trigger: 'blur' },
          { min: 5, max: 30, message: '标题5-30个字符串', trigger: 'blur' }
        ],
        content: [
          { required: true, message: '请输入文章内容', trigger: 'blur' }
        ],
        channel_id: [
          { required: true, message: '请选择文章频道', trigger: 'change' }
        ],
        // 单选项框组绑定的是 articleForm.cover.type 它能触发change来进行校验
        'cover.type': [
          { validator: validCoverFn, trigger: 'change' }
        ]
      },
      // 富文本配置对象
      editorOption: {
        placeholder: '请输入文章内容',
        modules: {
          toolbar: [
            ['bold', 'italic', 'underline', 'strike'],
            ['blockquote', 'code-block'],
            [{ header: 1 }, { header: 2 }],
            [{ list: 'ordered' }, { list: 'bullet' }],
            [{ indent: '-1' }, { indent: '+1' }],
            ['image']
          ]
        }
      }
    }
  },
  created () {
    // 如果组件初始化，默认发布文章场景
    // 如果是编辑文章，咱们才有事情去做，填充表单
    if (this.$route.query.id) {
      this.getArticle()
    }
  },
  watch: {
    // 监听地址栏ID数据的变化，去区分两种业务场景
    '$route.query.id': function () {
      if (this.$route.query.id) {
        // 修改文章 + 填充表单
        this.getArticle()
      } else {
        // 发布文章 + 重置表单（还原数据，清除校验）
        this.$refs.articleForm.resetFields()
        // 复杂数据类型饿了么没有清除，手动清除下
        this.articleForm.cover.images = []
      }
    }
  },
  methods: {
    // 修改文章
    editArticle () {
      // 整体表单校验
      this.$refs.articleForm.validate(async valid => {
        if (valid) {
          try {
            // 进行修改请求
            await this.$http.put(`articles/${this.$route.query.id}?draft=false`, this.articleForm)
            this.$message.success('修改文章成功')
            this.$router.push('/article')
          } catch (e) {
            this.$message.error('修改文章失败')
          }
        }
      })
    },
    // 获取文章+填充表单
    async getArticle () {
      const res = await this.$http.get(`articles/${this.$route.query.id}`)
      this.articleForm = res.data.data
    },
    // 添加文章
    saveArticle (draft) {
      // 整体表单校验
      this.$refs.articleForm.validate(async valid => {
        if (valid) {
          try {
            // 进行添加请求
            await this.$http.post(`articles?draft=${draft}`, this.articleForm)
            // 成功提示
            this.$message.success(draft ? '存入草稿成功' : '发布文章成功')
            // 跳转内容管理
            this.$router.push('/article')
          } catch (e) {
            // 失败提示
            this.$message.error(draft ? '存入草稿失败' : '发布文章失败')
          }
        }
      })
    },
    // 触发文章内容校验
    checkContent () {
      // 通过表单组件来使用声明好的content校验规则去校验content字段
      // 表单组件提供一个函数：validateField('字段名字') 进行校验
      this.$refs.articleForm.validateField('content')
    },
    // 触发文章封面校验
    checkCover () {
      // 触发cover.type校验规则，去校验封面图数据
      this.$refs.articleForm.validateField('cover.type')
    }
  }
}
</script>

<style scoped lang='less'>
// ::v-deep 是深度作用符号，让选择器在其他组件下也生效。
.container-publish ::v-deep .ql-editor {
  height: 250px;
}
::v-deep .ql-toolbar.ql-snow {
  padding: 0 8px;
}
</style>
